﻿using System;
using System.Collections.Generic;
using Assist;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.Revit;

namespace YArchitech.HVAC
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class HYPipeConnectHSprinklersByRectangle : IExternalCommand
	{
		public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			UIDocument activeUIDocument = commandData.Application.ActiveUIDocument;
			Document document = activeUIDocument.Document;
			Selection selection = activeUIDocument.Selection;
			ISelectionFilter pipingAndEquipmentFilter = new PipeAndSprinklersSelectionFilter();
			ISelectionFilter pipingFilter = new SprinlkersPipeSelectionFilter();
			ISelectionFilter equipmentFilter = new PipeSprinklersSelectionFilter();
			HYPipeConnect hypipeConnect = new HYPipeConnect();
			int num = 0;
			for (;;)
			{
				Transaction transaction = new Transaction(document, "水管连接喷头");
				try
				{
					if (num != 0)
					{
						RevitVersionFuncs.ClearSelection(selection);
					}
					num++;
					Pipe pipe = null;
					IList<Element> list = new List<Element>();
					SelectionTypePara selectionTypePara = new SelectionTypePara(BuiltInCategory.OST_PipeCurves, BuiltInCategory.OST_Sprinklers, pipingFilter, equipmentFilter, pipingAndEquipmentFilter, "请框选水管", "请框选喷头", "请框选水管和喷头");
					List<Element> list2 = RevitAPIUIOperate.SelectionCheck(selection, selectionTypePara, document);
					transaction.Start();
					int num2 = 0;
					bool flag = false;
					bool flag2 = false;
					IList<Pipe> list3 = new List<Pipe>();
					foreach (Element element in list2)
					{
						if (this.isUpDownSprinklerPipe(element))
						{
							list3.Add(element as Pipe);
							flag2 = true;
						}
						if (element is Pipe && !YJKRevitTools.isRiserPiping(element))
						{
							if (num2 == 0)
							{
								pipe = (element as Pipe);
							}
							else if (num2 == 1)
							{
								YJKMessageBox.Information("选择了多个管道，请重新选择");
								flag = true;
								RevitVersionFuncs.ClearSelection(selection);
								transaction.Commit();
								break;
							}
							num2++;
						}
						else if (element is FamilyInstance)
						{
							list.Add(element);
						}
					}
					if (flag)
					{
						continue;
					}
					if (pipe != null || list.Count >= 1)
					{
						if (pipe == null || list.Count < 1)
						{
							YJKMessageBox.Information("请至少选择一条喷淋系统管道和喷头进行连接");
						}
						else
						{
							SprinklerShelter sprinklerShelter = new SprinklerShelter();
							ICollection<ElementId> priorFitting = sprinklerShelter.GetPriorFitting(document);
							PipeType pipeType = pipe.PipeType;
							HYPipeConnect hypipeConnect2 = new HYPipeConnect();
							if (hypipeConnect2.judgeWhatConnectFunction(list))
							{
								if (!hypipeConnect2.PipeConnectCeSprinkler(list, pipe))
								{
									transaction.RollBack();
									YJKMessageBox.Information("连接失败");
									break;
								}
							}
							else if (flag2)
							{
								if (!hypipeConnect2.ConnUpDownSprinkler(list3, pipe))
								{
									transaction.RollBack();
									YJKMessageBox.Information("连接失败");
									break;
								}
							}
							else
							{
								ConnectHelper connectHelper = new ConnectHelper();
								Connector conn = connectHelper.GetPipeConnectorEnd(pipe)[0];
								bool flag3 = true;
								int num3 = 0;
								foreach (Element elem in list)
								{
									num3 = ConnectHelper.CheckPositionBetweenElement(connectHelper.GetYJKElementConnector(elem), conn);
									if (3 == num3)
									{
										flag3 = false;
										break;
									}
								}
								if (!flag3)
								{
									YJKMessageBox.Information("不能完成连接，喷头必须在水平面上，请重新选择");
									RevitVersionFuncs.ClearSelection(selection);
									break;
								}
								SprinklerConnTypeSetForm sprinklerConnTypeSetForm = new SprinklerConnTypeSetForm();
								int num4 = (int)sprinklerConnTypeSetForm.ShowDialog();
								string connType = sprinklerConnTypeSetForm.connType;
								if (num4 == 1)
								{
									bool flag4 = false;
									if (connType == "1" && num3 == 0)
									{
										flag4 = hypipeConnect.PipeConnectHSprinklersByRectangle(pipe, list, this.GetPipeConnectType(pipe));
									}
									else if (connType == "2")
									{
										flag4 = hypipeConnect.PipeConnectHSprinklersByRectangleType2(pipe, list, sprinklerConnTypeSetForm.dMainBranchPipeOffset);
									}
									else
									{
										if (num3 == 1)
										{
											YJKMessageBox.Information("下喷喷头连接时，主管应该在喷头上方。或者选择第二种连接方式。");
											break;
										}
										if (num3 == 2)
										{
											YJKMessageBox.Information("上喷喷头连接时，主管应该在喷头下方。或者选择第二种连接方式。");
											break;
										}
									}
									if (!flag4)
									{
										YJKMessageBox.Information("空间位置不足，连接失败。");
										transaction.RollBack();
										break;
									}
									RevitVersionFuncs.ClearSelection(selection);
								}
							}
							sprinklerShelter.SetAfterFitting(document, priorFitting, (list[0] as FamilyInstance).Symbol, pipeType, false, null);
						}
					}
					document.Regenerate();
					continue;
				}
				catch (Autodesk.Revit.Exceptions.OperationCanceledException)
				{
					return Autodesk.Revit.UI.Result.Succeeded;
				}
				catch (Exception ex)
				{
					YJKMessageBox.Error(ex.Message);
					continue;
				}
				finally
				{
					if (transaction != null)
					{
						TransactionStatus status = transaction.GetStatus();
						if ((int)status == 1)
						{
							transaction.Commit();
						}
						else if ((int)status == 5)
						{
							transaction.RollBack();
						}
					}
				}
				break;
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private int GetPipeConnectType(Pipe pipe)
		{
			return pipe.PipeType.get_Parameter(BuiltInParameter.RBS_CURVETYPE_PREFERRED_BRANCH_PARAM).AsInteger();
		}

		private bool isUpDownSprinklerPipe(Element elem)
		{
			bool result = false;
			if (elem is Pipe && YJKRevitTools.isRiserPiping(elem))
			{
				List<Connector> pipeConnConnector = YJKRevitTools.GetPipeConnConnector(elem as Pipe);
				Connector connectConnector = YJKRevitTools.GetConnectConnector(pipeConnConnector[0]);
				Connector connectConnector2 = YJKRevitTools.GetConnectConnector(pipeConnConnector[1]);
				if (-2008099 == connectConnector.Owner.Category.Id.IntegerValue && -2008099 == connectConnector2.Owner.Category.Id.IntegerValue)
				{
					result = true;
				}
			}
			return result;
		}
	}
}
